package com.meiyuetao.myt.stock.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import lab.s2jh.auth.entity.Department;
import lab.s2jh.auth.entity.User;
import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.web.json.DateJsonSerializer;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.envers.NotAudited;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.meiyuetao.myt.core.constant.VoucherStateEnum;
import com.meiyuetao.myt.core.entity.MytBaseEntity;
import com.meiyuetao.myt.purchase.entity.Supplier;

@MetaData("库存调拨单")
@Entity
@Table(name = "myt_commodity_stock_move")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class CommodityStockMove extends MytBaseEntity {
    private static final long serialVersionUID = 1L;
    @MetaData("唯一凭证号")
    private String voucher;
    @MetaData("凭证日期")
    private Date voucherDate;
    @MetaData("凭证状态")
    private VoucherStateEnum voucherState = VoucherStateEnum.DRAFT;
    @MetaData("经办人")
    private User voucherUser;
    @MetaData("经办部门")
    private Department voucherDepartment;
    @MetaData("备注信息")
    private String memo;
    private List<CommodityStockMoveDetail> commodityStockMoveDetails = new ArrayList<CommodityStockMoveDetail>();

    @MetaData("快递公司")
    private Supplier logistics;

    @MetaData("快递单号")
    private String logisticsNo;

    @MetaData("运费")
    private BigDecimal totalDeliveryAmount;
    @MetaData("原始库存地")
    private StorageLocation originStorageLocation;

    @MetaData("目的库存地")
    private StorageLocation destinationStorageLocation;

    @MetaData("采购单总入库价值金额")
    private BigDecimal totalCostAmount;

    // 出库单相关信息
    @MetaData("发货方式")
    private String deliveryMode;

    @MetaData("提货人")
    private String pickUpPerson;
    @MetaData("提货人单位")
    private String pickUpCompany;
    @MetaData("提货人电话")
    private String pickUpMobile;
    @MetaData("提货日期")
    private Date pickUpDate;
    @MetaData("出库审核人")
    private String pickUpAuditBy;
    @MetaData("发货地址信息")
    private String deliveryAddr;

    @Column(length = 128, nullable = false, unique = true, updatable = false)
    @JsonProperty
    public String getVoucher() {
        return voucher;
    }

    public void setVoucher(String voucher) {
        this.voucher = voucher;
    }

    @Column(nullable = false)
    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getVoucherDate() {
        return voucherDate;
    }

    public void setVoucherDate(Date voucherDate) {
        this.voucherDate = voucherDate;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = true)
    @JsonProperty
    public VoucherStateEnum getVoucherState() {
        return voucherState;
    }

    public void setVoucherState(VoucherStateEnum voucherState) {
        this.voucherState = voucherState;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_user_id", nullable = false)
    @JsonProperty
    public User getVoucherUser() {
        return voucherUser;
    }

    public void setVoucherUser(User voucherUser) {
        this.voucherUser = voucherUser;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_department_id", nullable = false)
    @JsonProperty
    public Department getVoucherDepartment() {
        return voucherDepartment;
    }

    public void setVoucherDepartment(Department voucherDepartment) {
        this.voucherDepartment = voucherDepartment;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @OneToMany(mappedBy = "commodityStockMove", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<CommodityStockMoveDetail> getCommodityStockMoveDetails() {
        return commodityStockMoveDetails;
    }

    public void setCommodityStockMoveDetails(List<CommodityStockMoveDetail> commodityStockMoveDetails) {
        this.commodityStockMoveDetails = commodityStockMoveDetails;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "logistics_sid")
    @NotAudited
    @JsonProperty
    public Supplier getLogistics() {
        return logistics;
    }

    public void setLogistics(Supplier logistics) {
        this.logistics = logistics;
    }

    @JsonProperty
    public String getLogisticsNo() {
        return logisticsNo;
    }

    public void setLogisticsNo(String logisticsNo) {
        this.logisticsNo = logisticsNo;
    }

    @ManyToOne
    @JoinColumn(name = "origin_storage_location_sid", nullable = false)
    @NotAudited
    @JsonProperty
    public StorageLocation getOriginStorageLocation() {
        return originStorageLocation;
    }

    public void setOriginStorageLocation(StorageLocation originStorageLocation) {
        this.originStorageLocation = originStorageLocation;
    }

    @ManyToOne
    @JoinColumn(name = "destination_storage_location_sid", nullable = false)
    @NotAudited
    @JsonProperty
    public StorageLocation getDestinationStorageLocation() {
        return destinationStorageLocation;
    }

    public void setDestinationStorageLocation(StorageLocation destinationStorageLocation) {
        this.destinationStorageLocation = destinationStorageLocation;
    }

    public BigDecimal getTotalCostAmount() {
        return totalCostAmount;
    }

    public void setTotalCostAmount(BigDecimal totalCostAmount) {
        this.totalCostAmount = totalCostAmount;
    }

    public BigDecimal getTotalDeliveryAmount() {
        return totalDeliveryAmount;
    }

    public void setTotalDeliveryAmount(BigDecimal totalDeliveryAmount) {
        this.totalDeliveryAmount = totalDeliveryAmount;
    }

    @JsonProperty
    public String getDeliveryMode() {
        return deliveryMode;
    }

    public void setDeliveryMode(String deliveryMode) {
        this.deliveryMode = deliveryMode;
    }

    @JsonProperty
    public String getPickUpPerson() {
        return pickUpPerson;
    }

    public void setPickUpPerson(String pickUpPerson) {
        this.pickUpPerson = pickUpPerson;
    }

    @JsonProperty
    public String getPickUpCompany() {
        return pickUpCompany;
    }

    public void setPickUpCompany(String pickUpCompany) {
        this.pickUpCompany = pickUpCompany;
    }

    @JsonProperty
    public String getPickUpMobile() {
        return pickUpMobile;
    }

    public void setPickUpMobile(String pickUpMobile) {
        this.pickUpMobile = pickUpMobile;
    }

    @JsonProperty
    public String getPickUpAuditBy() {
        return pickUpAuditBy;
    }

    public void setPickUpAuditBy(String pickUpAuditBy) {
        this.pickUpAuditBy = pickUpAuditBy;
    }

    @JsonSerialize(using = DateJsonSerializer.class)
    @JsonProperty
    public Date getPickUpDate() {
        return pickUpDate;
    }

    public void setPickUpDate(Date pickUpDate) {
        this.pickUpDate = pickUpDate;
    }

    public String getDeliveryAddr() {
        return deliveryAddr;
    }

    public void setDeliveryAddr(String deliveryAddr) {
        this.deliveryAddr = deliveryAddr;
    }

}
